import validator from 'express-validator';
import { isPoly } from '../../common/utils/polyvinyl';

const isObject = val => !!val && typeof val === 'object';

export default function() {
  return validator({
    customValidators: {
      matchRegex(param, regex) {
        return regex.test(param);
      },
      isString(value) {
        return typeof value === 'string';
      },
      isNumber(value) {
        return typeof value === 'number';
      },
      isFiles(value) {
        if (!isObject(value)) {
          return false;
        }
        const keys = Object.keys(value);
        return (
          !!keys.length &&
          // every key is a file
          keys.every(key => isObject(value[key])) &&
          // every file has contents
          keys.map(key => value[key]).every(file => isPoly(file))
        );
      }
    },
    customSanitizers: {
      // Refer : http://stackoverflow.com/a/430240/1932901
      trimTags(value) {
        const tagBody = '(?:[^"\'>]|"[^"]*"|\'[^\']*\')*';
        const tagOrComment = new RegExp(
          '<(?:' +
            // Comment body.
            '!--(?:(?:-*[^->])*--+|-?)' +
            // Special "raw text" elements whose content should be elided.
            '|script\\b' +
            tagBody +
            '>[\\s\\S]*?</script\\s*' +
            '|style\\b' +
            tagBody +
            '>[\\s\\S]*?</style\\s*' +
            // Regular name
            '|/?[a-z]' +
            tagBody +
            ')>',
          'gi'
        );
        let rawValue;
        do {
          rawValue = value;
          value = value.replace(tagOrComment, '');
        } while (value !== rawValue);

        return value.replace(/</g, '&lt;');
      }
    }
  });
}
